home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / QuickDraw3D 1.6 SDK / Mac SampleCode Previous / Geometry Samples- Mac / Skinny3DSample / Skinny3DSources ƒ / Lights.c < prev    next >
Encoding:
Text File  |  1999-05-18  |  12.2 KB  |  364 lines  |  [TEXT/MPS ]

  1. // file Lights.c
  2.  
  3. #include <Types.h>
  4.  
  5.  
  6. #include "SkinnyMain.h"
  7. #include "Lights.h"
  8. // #include "ValueControls.h"
  9.  
  10. // local prototypes
  11. static VccPtr     LightDataToVcc        (TQ3LightData               lightData);
  12. static VccPtr     DirectLightDataToVcc(TQ3DirectionalLightData drLightData);
  13. static VccPtr     PointLightDataToVcc    (TQ3PointLightData         ptLightData);
  14. static VccPtr     SpotLightDataToVcc    (TQ3SpotLightData         spLightData);
  15. static void     AddStdLightDataValues(VccPtr vcc, TQ3LightData lightData);
  16.  
  17. static void    VccToLightData        (VccPtr vcc, TQ3LightData               *lightData);
  18. static void    VccToDirectLightData(VccPtr vcc, TQ3DirectionalLightData *drLightData);
  19. static void    VccToPointLightData    (VccPtr vcc, TQ3PointLightData         *ptLightData);
  20. static void    VccToSpotLightData    (VccPtr vcc, TQ3SpotLightData         *spLightData);
  21. static void GetStdLightDataValues(VccPtr vcc, TQ3LightData             *lightData);
  22.  
  23. static TQ3LightObject FindLight(TQ3GroupObject lightGroup, TQ3ObjectType lType);
  24.  
  25. extern Rect gContrlRect;
  26.  
  27.  
  28. // --------------------------------------------------------------------
  29. TQ3GroupObject MakeLights(void)
  30. {
  31.     TQ3GroupPosition            groupPosition;
  32.     TQ3GroupObject            lightGroup;
  33.     TQ3LightData                lightData;
  34.     TQ3PointLightData        pointLightData;
  35.     TQ3DirectionalLightData    directLightData;
  36.     TQ3SpotLightData            spotLightData;
  37.     TQ3LightObject            ambientLight, pointLight, fillLight, spotLight;
  38.     TQ3Point3D                pointLocation = { -10.0, 0.0, 10.0 };
  39.     TQ3Vector3D                fillDirection = { -5.0, 0.0, 10.0 };
  40.     TQ3Point3D                spotLocation = { -10.0, 10.0, 10.0 };
  41.     TQ3Vector3D                spotDirection = { 10.0, -10.0, -10.0 };
  42.     TQ3ColorRGB                WhiteLight = { 1.0, 1.0, 1.0 };
  43.     
  44.     //    Set up light data for ambient light.  This light data will be used for point and fill
  45.     //    light also.
  46.  
  47.     lightData.isOn          = kQ3True;
  48.     lightData.color      = WhiteLight;
  49.     lightData.brightness = .2;
  50.     
  51.     //    Create ambient light.
  52.     ambientLight = Q3AmbientLight_New(&lightData);
  53.     if ( ambientLight == nil ) goto bail;
  54.     
  55.     //    Create point light.
  56.     lightData.brightness = 1.0;
  57.     pointLightData.lightData         = lightData;
  58.     pointLightData.castsShadows     = kQ3False;
  59.     pointLightData.attenuation         = kQ3AttenuationTypeNone;
  60.     pointLightData.location         = pointLocation;
  61.     pointLight = Q3PointLight_New(&pointLightData);
  62.     if ( pointLight == nil ) goto bail;
  63.  
  64.     //    Create fill light.
  65.     lightData.brightness = .8;
  66.     directLightData.lightData         = lightData;
  67.     directLightData.castsShadows     = kQ3False;
  68.     directLightData.direction         = fillDirection;
  69.     fillLight = Q3DirectionalLight_New(&directLightData);
  70.     if ( fillLight == nil ) goto bail;
  71.  
  72.     //    Create spot light.
  73.     lightData.brightness = .4;
  74.     spotLightData.lightData     = lightData;
  75.     spotLightData.castsShadows     = kQ3False;
  76.     spotLightData.attenuation     = kQ3AttenuationTypeNone;
  77.     spotLightData.location         = spotLocation;
  78.     spotLightData.direction     = spotDirection;
  79.     spotLightData.hotAngle         = 0.2;
  80.     spotLightData.outerAngle     = 0.4;
  81.     spotLightData.fallOff         = kQ3FallOffTypeLinear;
  82.     
  83.     spotLight = Q3SpotLight_New(&spotLightData);
  84.     if ( spotLight == nil ) goto bail;
  85.  
  86.     //    Create light group and add each of the lights into the group.
  87.     lightGroup = Q3LightGroup_New();
  88.     if ( lightGroup == nil ) goto bail;
  89.     
  90.     groupPosition = Q3Group_AddObject(lightGroup, ambientLight);
  91.     if ( groupPosition == 0 ) goto bail;
  92.     groupPosition = Q3Group_AddObject(lightGroup, pointLight);
  93.     if ( groupPosition == 0 ) goto bail;
  94.     groupPosition = Q3Group_AddObject(lightGroup, fillLight);
  95.     if ( groupPosition == 0 ) goto bail;
  96.     groupPosition = Q3Group_AddObject(lightGroup, spotLight);
  97.     if ( groupPosition == 0 ) goto bail;
  98.  
  99.     //    Done!
  100.     return ( lightGroup );
  101.     
  102. bail: // If any of the above failed, then return nothing!
  103.     return ( nil );
  104. }
  105.  
  106.  
  107. // --------------------------------------------------------------------
  108. static TQ3LightObject FindLight(TQ3GroupObject lightGroup, TQ3ObjectType lType)
  109. {
  110.     TQ3Status        status;
  111.     TQ3Object        object;
  112.     TQ3LightObject     light;
  113.     TQ3GroupPosition    position;
  114.     Boolean            found = false;
  115.  
  116.     status = Q3Group_GetFirstPosition(lightGroup, &position);
  117.     if (status != kQ3Success)
  118.         return NULL;
  119.     do {
  120.         status = Q3Group_GetPositionObject(lightGroup, position, &object);
  121.         if (object == NULL)
  122.             return NULL;
  123.         light = (TQ3LightObject)object;
  124.         found = (Q3Light_GetType(light) == lType);
  125.         status = Q3Group_GetNextPosition(lightGroup, &position);
  126.     } while ((!found) && (position != NULL));
  127.     if (found)
  128.         return light;
  129.     else
  130.         return NULL;
  131. }
  132.  
  133.  
  134. // --------------------------------------------------------------------
  135. VccPtr     LightToVCC(TQ3GroupObject lightGroup, long selector)
  136. {
  137.     TQ3LightObject     light;
  138.     TQ3Status        status;
  139.     TQ3ObjectType    lType;
  140.     TQ3LightData                lightData;
  141.     TQ3DirectionalLightData    drLightData;
  142.     TQ3PointLightData        ptLightData;
  143.     TQ3SpotLightData            spLightData;
  144.     
  145.     switch (selector) {
  146.         case iAmbient:         lType = kQ3LightTypeAmbient;        break;
  147.         case iDirectional:     lType = kQ3LightTypeDirectional;    break;
  148.         case iPoint:         lType = kQ3LightTypePoint;            break;
  149.         case iSpot:         lType = kQ3LightTypeSpot;            break;
  150.         default:    return nil;
  151.     }
  152.     light = FindLight(lightGroup, lType);
  153.     
  154.     switch (selector) {
  155.         case iAmbient:
  156.                 status = Q3AmbientLight_GetData(light, &lightData);
  157.                 return LightDataToVcc(lightData);
  158.             break;
  159.         case iDirectional:
  160.                 status = Q3DirectionalLight_GetData(light, &drLightData);
  161.                 return DirectLightDataToVcc(drLightData);
  162.             break;
  163.         case iPoint:
  164.                 status = Q3PointLight_GetData(light, &ptLightData);
  165.                 return PointLightDataToVcc(ptLightData);
  166.             break;
  167.         case iSpot:
  168.                 status = Q3SpotLight_GetData(light, &spLightData);
  169.                 return SpotLightDataToVcc(spLightData);
  170.             break;
  171.         default:
  172.             return nil;
  173.     }
  174. }
  175.  
  176.  
  177. #define cBasicLines 7
  178.  
  179. // --------------------------------------------------------------------
  180. static VccPtr     LightDataToVcc(TQ3LightData lightData)
  181. {
  182.     VccPtr         vcc;
  183.  
  184.     vcc = NewVCluster((long)kQ3LightTypeAmbient, "\pAmbientLightData", cBasicLines, &gContrlRect);
  185.     if (vcc == nil) return nil;
  186.     AddStdLightDataValues(vcc, lightData);
  187.     return vcc;
  188. }
  189.  
  190.  
  191. // --------------------------------------------------------------------
  192. static VccPtr     DirectLightDataToVcc(TQ3DirectionalLightData drLightData)
  193. {
  194.     VccPtr         vcc;
  195.  
  196.     vcc = NewVCluster((long)kQ3LightTypeDirectional, "\pDirectionalLightData", 
  197.                                                                 cBasicLines + 4, &gContrlRect);
  198.     if (vcc == nil) return nil;
  199.     AddStdLightDataValues(vcc, drLightData.lightData);
  200.     AddValueCtl(vcc, "\pcastsShadows", drLightData.castsShadows,   0.0, 1.0, 1.0); // [7]
  201.     AddValueCtl(vcc, "\pdirection.x",  drLightData.direction.x,  -30.0, 30.0, 3.0);
  202.     AddValueCtl(vcc, "\pdirection.y",  drLightData.direction.y,  -30.0, 30.0, 3.0);
  203.     AddValueCtl(vcc, "\pdirection.z",  drLightData.direction.z,  -30.0, 30.0, 3.0);
  204.     return vcc;
  205. }
  206.  
  207.  
  208. // --------------------------------------------------------------------
  209. static VccPtr     PointLightDataToVcc(TQ3PointLightData ptLightData)
  210. {
  211.     VccPtr         vcc;
  212.  
  213.     vcc = NewVCluster((long)kQ3LightTypePoint, "\pPointLightData", cBasicLines + 6, &gContrlRect);
  214.     if (vcc == nil) return nil;
  215.     AddStdLightDataValues(vcc, ptLightData.lightData);
  216.     AddValueCtl(vcc, "\pcastsShadows", ptLightData.castsShadows, 0.0, 1.0, 1.0); // [7]
  217.     AddValueCtl(vcc, "\pattenuation", ptLightData.attenuation,     0.0,  2.0, 1.0);
  218.     AddSeparator(vcc);
  219.     AddValueCtl(vcc, "\plocation.x", ptLightData.location.x,  -30.0, 30.0, 3.0); // [10]
  220.     AddValueCtl(vcc, "\plocation.y", ptLightData.location.y,  -30.0, 30.0, 3.0);
  221.     AddValueCtl(vcc, "\plocation.z", ptLightData.location.z,  -30.0, 30.0, 3.0);
  222.     return vcc;
  223. }
  224.  
  225.  
  226. // --------------------------------------------------------------------
  227. static VccPtr     SpotLightDataToVcc(TQ3SpotLightData spLightData)
  228. {
  229.     VccPtr         vcc;
  230.  
  231.     vcc = NewVCluster((long)kQ3LightTypeSpot, "\pSpotLightData", cBasicLines + 14, &gContrlRect);
  232.     if (vcc == nil) return nil;
  233.     AddStdLightDataValues(vcc, spLightData.lightData);
  234.     AddValueCtl(vcc, "\pcastsShadows", spLightData.castsShadows, 0.0, 1.0, 1.0); // [7]
  235.     AddValueCtl(vcc, "\pattenuation", spLightData.attenuation,     0.0,  2.0, 1.0);
  236.     AddSeparator(vcc);
  237.     AddValueCtl(vcc, "\plocation.x", spLightData.location.x,  -30.0, 30.0, 3.0); // [10]
  238.     AddValueCtl(vcc, "\plocation.y", spLightData.location.y,  -30.0, 30.0, 3.0);
  239.     AddValueCtl(vcc, "\plocation.z", spLightData.location.z,  -30.0, 30.0, 3.0);
  240.     AddSeparator(vcc);
  241.     AddValueCtl(vcc, "\pdirection.x", spLightData.direction.x,  -30.0, 30.0, 3.0); // [14]
  242.     AddValueCtl(vcc, "\pdirection.y", spLightData.direction.y,  -30.0, 30.0, 3.0);
  243.     AddValueCtl(vcc, "\pdirection.z", spLightData.direction.z,  -30.0, 30.0, 3.0);
  244.     AddSeparator(vcc);
  245.     AddValueCtl(vcc, "\photAngle",   spLightData.hotAngle,     0.05, 1.0, 0.05);  // [18]
  246.     AddValueCtl(vcc, "\pouterAngle", spLightData.outerAngle, 0.1, 2.0, 0.1);
  247.     AddValueCtl(vcc, "\pfallOff",      spLightData.fallOff,     0.0, 3.0, 1.0);
  248.     return vcc;
  249. }
  250.  
  251.  
  252. // --------------------------------------------------------------------
  253. static void AddStdLightDataValues(VccPtr vcc, TQ3LightData lightData)
  254. {
  255.     AddValueCtl(vcc, "\pisOn",         lightData.isOn,          0.0, 1.0, 1.0); // [0]
  256.     AddValueCtl(vcc, "\pbrightness",lightData.brightness, 0.0, 1.0, 0.1);
  257.     AddSeparator(vcc);
  258.     AddValueCtl(vcc, "\pcolor.r",     lightData.color.r,      0.0, 1.0, 0.1); // [3]
  259.     AddValueCtl(vcc, "\pcolor.g",     lightData.color.g,       0.0, 1.0, 0.1);
  260.     AddValueCtl(vcc, "\pcolor.b",     lightData.color.b,       0.0, 1.0, 0.1);
  261.     AddSeparator(vcc); // cBasicLines = 7
  262. }
  263.  
  264.  
  265. // --------------------------------------------------------------------
  266. void VCCtoLight(VccPtr vcc, TQ3GroupObject lightGroup)
  267. {
  268.     TQ3LightData                lightData;
  269.     TQ3DirectionalLightData    drLightData;
  270.     TQ3PointLightData        ptLightData;
  271.     TQ3SpotLightData            spLightData;
  272.     TQ3Status                status;
  273.     TQ3LightObject             light;
  274.     TQ3ObjectType            lType;
  275.     
  276.     lType = (TQ3ObjectType)GetIdTag(vcc);
  277.     light = FindLight(lightGroup, lType);
  278.     if (light == NULL)
  279.         return;
  280.         
  281.     switch    (lType) {
  282.         case kQ3LightTypeAmbient:
  283.                 VccToLightData(vcc, &lightData);
  284.                 status = Q3AmbientLight_SetData(light, &lightData);
  285.             break;
  286.         case kQ3LightTypeDirectional:
  287.                 VccToDirectLightData(vcc, &drLightData);
  288.                 status = Q3DirectionalLight_SetData(light, &drLightData);
  289.             break;
  290.         case kQ3LightTypePoint:
  291.                 VccToPointLightData(vcc, &ptLightData);
  292.                 status = Q3PointLight_SetData(light, &ptLightData);
  293.             break;
  294.         case kQ3LightTypeSpot:
  295.                 VccToSpotLightData(vcc, &spLightData);
  296.                 status = Q3SpotLight_SetData(light, &spLightData);
  297.             break;
  298.     }
  299. }
  300.  
  301.  
  302. // --------------------------------------------------------------------
  303. static void    VccToLightData(VccPtr vcc, TQ3LightData *lightData)
  304. {
  305.     lightData->isOn            = (GetCurrentValue(vcc, 0) == 1.0);
  306.     lightData->brightness    = GetCurrentValue(vcc, 1);
  307.     lightData->color.r        = GetCurrentValue(vcc, 3);
  308.     lightData->color.g        = GetCurrentValue(vcc, 4);
  309.     lightData->color.b        = GetCurrentValue(vcc, 5);
  310. }
  311.  
  312.  
  313. // --------------------------------------------------------------------
  314. static void    VccToDirectLightData(VccPtr vcc, TQ3DirectionalLightData *drLightData)
  315. {
  316.     VccToLightData(vcc, &drLightData->lightData);
  317.  
  318.     drLightData->castsShadows    = (GetCurrentValue(vcc, 7) == 1.0);
  319.     
  320.     drLightData->direction.x    = GetCurrentValue(vcc, 8);
  321.     drLightData->direction.y    = GetCurrentValue(vcc, 9);
  322.     drLightData->direction.z    = GetCurrentValue(vcc, 10);
  323. }
  324.  
  325.  
  326. // --------------------------------------------------------------------
  327. static void    VccToPointLightData (VccPtr vcc, TQ3PointLightData *ptLightData)
  328. {
  329.     VccToLightData(vcc, &ptLightData->lightData);
  330.  
  331.     ptLightData->castsShadows    = (GetCurrentValue(vcc, 7) == 1.0);
  332.     ptLightData->attenuation      = GetCurrentValue(vcc, 8); // 0, 1, 2
  333.     
  334.     ptLightData->location.x        = GetCurrentValue(vcc, 10);
  335.     ptLightData->location.y        = GetCurrentValue(vcc, 11);
  336.     ptLightData->location.z        = GetCurrentValue(vcc, 12);
  337. }
  338.  
  339.  
  340.  
  341. // --------------------------------------------------------------------
  342. static void    VccToSpotLightData (VccPtr vcc, TQ3SpotLightData *spLightData)
  343. {
  344.     VccToLightData(vcc, &spLightData->lightData);
  345.     
  346.     spLightData->castsShadows    = (GetCurrentValue(vcc, 7) == 1.0);
  347.     spLightData->attenuation      = GetCurrentValue(vcc, 8); // 0, 1, 2
  348.     
  349.     spLightData->location.x        = GetCurrentValue(vcc, 10);
  350.     spLightData->location.y        = GetCurrentValue(vcc, 11);
  351.     spLightData->location.z        = GetCurrentValue(vcc, 12);
  352.     
  353.     spLightData->direction.x    = GetCurrentValue(vcc, 14);
  354.     spLightData->direction.y    = GetCurrentValue(vcc, 15);
  355.     spLightData->direction.z    = GetCurrentValue(vcc, 16);
  356.  
  357.     spLightData->hotAngle        = GetCurrentValue(vcc, 18);
  358.     spLightData->outerAngle        = GetCurrentValue(vcc, 19);
  359.     spLightData->fallOff        = GetCurrentValue(vcc, 20); // 0, 1, 2, 3
  360. }
  361.  
  362.  
  363.  
  364.